home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Apple Developer Connection Student Program
/
ADC Tools Sampler CD Disk 3 1999.iso
/
Cool Demos, SDKs, & Tools
/
Demos⁄Tools⁄Offers
/
Alpha ƒ
/
Tcl
/
Packages
/
Docprojects.tcl
< prev
next >
Wrap
Text File
|
1999-04-26
|
34KB
|
1,035 lines
## -*-Tcl-*-
# ###################################################################
# Vince's Additions - an extension package for Alpha
#
# FILE: "Docprojects.tcl"
# created: 29/7/97 {4:59:22 pm}
# last update: 04/26/1999 {16:32:59 PM}
# Author: Vince Darley
# E-mail: <darley@fas.harvard.edu>
# mail: Division of Engineering and Applied Sciences, Harvard University
# Oxford Street, Cambridge MA 02138, USA
# www: <http://www.fas.harvard.edu/~darley/>
#
# Copyright (c) 1997-1999 Vince Darley, all rights reserved
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
# ###################################################################
##
alpha::extension documentProjects 1.6.4 {
set alpha::prefs(documentProjects) Docproj
alpha::package require AlphaTcl 7.2fc7
namespace eval Docproj {}
# dummy value
ensureset docProject(name) [list "None" "Project2" "Thesis"]
# The name of the current project. Every project has a unique name
newPref var currentProject "None" Docproj "" docProject(name) "varitem"
# Different identities can be useful if your projects may be sometimes
# for work purposes, sometimes for your own purposes etc.
newPref var identity Usual Docproj Docproj::changeIdentity identities "array"
menu::buildProc "Current Project" \
{menu::buildFlagMenu "Current Project" list currentProject DocprojmodeVars}
menu::insert packages submenu 1 {Current Project}
menu::insert packages items 1 \
"documentProjectPrefs…" "userDetails…" \
"<E<SremoveDocumentTemplate…" "<S<BeditDocumentTemplate…" \
"<SnewDocumentTemplate…" \
"<E<SremoveProject…" "<S<BeditProject…" "<SnewProject…"
# Key-binding to update the version number in a file's header.
# These version numbers can be inserted by some of the standard
# document templates.
newPref binding updateFileVersion "/f<U" Docproj
menu::insert winUtils items end \
"updateDate" \
"[menu::bind DocprojmodeVars(updateFileVersion) -]"
lunion elec::MenuTemplates "createHeader" "newDocument"
catch "unBind F1 bind::Completion"
menu::insert elec items end \
{Menu -n FunctionComments -p menu::generalProc {
"/eusual"
"/e<Isimple"
"/e<OwithAuthor"
"/e<Uupdate"
}}
hook::register requireOpenWindowsHook [list $electricMenu FunctionComments] 1
namespace eval newDocument {}
set "newDocument::handlers(Document Projects)" Docproj::newHandler
# Use this simple proc if we don't have the newDocument package.
if {![alpha::package exists newDocument]} {
;proc file::newDocument {} {
beep
Docproj::newHandler [list -n [statusPrompt "New doc name:"]]
}
} else {
alpha::package require newDocument
}
# When you request a new document, if this flag is set the user
# is only prompted with a list of document templates which
# are relevant to the current mode. This can be useful if you
# have lots of templates.
newPref flag docTemplatesModeSpecific 1 Docproj
# When a file is saved, its header (time-stamp) etc can be
# automatically updated.
newPref flag autoUpdateHeader 1 Docproj
# call on saveHook
proc Docproj::changeProject {name} {
if {$name == "*"} { return }
menu::flagProc "Current Project" $name
}
# call on saveHook
hook::register saveHook updateHeaderHook
} maintainer {
"Vince Darley" darley@fas.harvard.edu <http://www.fas.harvard.edu/~darley/>
} uninstall {this-file} help {file "Documentprojects Help"}
# user projects
if {![info exists docProject(addendum)]} {
set docProject(addendum) { {none} {about some other stuff} {deep problems}}
set docProject(default_modes) { {} {C++ Tcl} {TeX}}
set docProject(extra) [list "" "Freely distributable" "Copyright (C) 1997-1998 the author."]
set docProject(license) [list "" "" ""]
}
proc updateHeaderHook {name} {
global DocprojmodeVars
if {$DocprojmodeVars(autoUpdateHeader)} {
# update does no harm if it fails so we call it for all
# modes with no worries.
getWinInfo -w $name a
if {$a(dirty)} {
file::updateDate $name
}
}
}
# header/source templates (NOTE: FORMAT OF THIS LIST MAY CHANGE)
llunion elec::DocTemplates 1 \
{ * "Empty" * "" *} \
{ * "Default" * t_default *} \
{ TeX "Basic LaTeX document" "None" t_latex * {article report letter book slides}} \
{ C++ "Basic C++ header file" "Header" t_cpp_header * } \
{ C++ "Basic C++ source file" "Source" t_cpp_source * } \
{ HTML "HTML document" * t_html * }
##
# \
# { C++ "Cpptcl Class Source" Source t_cpptcl_source "Cpptcl"} \
# { C++ "Cpptcl Class Header" Header t_cpptcl_header "Cpptcl"} \
# { Tcl "Itcl Class" * t_itcl_class "Cpptcl"} \
# { Tcl "Blank Tcl Header" Header "\#" "Vince's Additions"} \
# { C++ "EvoX Class Source" Source t_cpptcl_source "EvoX"} \
# { C++ "EvoX Class Header" Header t_cpptcl_header "EvoX"}
##
# used for file description headers
if {$synchroniseWithInternetConfig} {
catch {set user(author) [icGetPref RealName]}
catch {set user(email) "<[icGetPref Email]>"}
catch {set user(www) "<[icGetPref WWWHomePage]>"}
catch {set user(organisation) [icGetPref Organization]}
}
ensureset user(author) "Ken McKen"
ensureset user(email) "ken@kenny.com"
ensureset user(www) "http://www.kenny.com/"
ensureset user(organisation) "Ken Corp."
ensureset user(address) "Rose St, MA 02143, USA"
ensureset user(author_initials) "VMD"
ensureset identities(Usual) [array get user]
proc Docproj::changeIdentity {var} {
global identities user DocprojmodeVars
array set user $identities($DocprojmodeVars($var))
}
if {[info exists DocprojmodeVars(identity)]} {
Docproj::changeIdentity identity
}
proc global::userDetails {} {
global DocprojmodeVars modifiedArrayElements user identities
set oldInfo [array get user]
if {[catch {dialog::pkg_options "Docprojects" \
"User Details (some may be from Internet Config)" 1 user}] \
|| ($oldInfo == [array get user])} {
return
}
set oldId $DocprojmodeVars(identity)
if {![dialog::yesno -y "Update" -n "New Identity" \
"Update $DocprojmodeVars(identity) identity, or make a new one?"]} {
# Ask for new name
set name [eval prompt [list "Enter tag for new identity" \
"<Tag>" "Old ids:"] [array names identities]]
set identities($name) [array get user]
set DocprojmodeVars(identity) $name
# Have to store Usual id too.
lappend modifiedArrayElements [list $name identities] \
[list identity DocprojmodeVars]
} else {
set identities($oldId) [array get user]
}
lappend modifiedArrayElements [list $oldId identities]
}
proc global::documentProjectPrefs {} {
dialog::pkg_options "Docproj" "Preferences for your Document Projects"
}
proc Docproj::newHandler {args} {
set doc [file::createDocument "new $args"]
if {[getModifiers] & 72} {
file::pickProject
}
file::createHeader $doc
return ""
}
proc file::pickProject {} {
global DocprojmodeVars docProject
set item [listpick -p "Pick a project…" -L $DocprojmodeVars(currentProject) \
$docProject(name)]
if {$item != ""} {Docproj::changeProject $item }
return $item
}
proc file::projectName {} {
global DocprojmodeVars
return $DocprojmodeVars(currentProject)
}
proc file::projectAddendum {} {
global docProject DocprojmodeVars
return [lindex $docProject(addendum) \
[lsearch -exact $docProject(name) $DocprojmodeVars(currentProject)]]
}
proc file::projectExtra {} {
global docProject DocprojmodeVars
return [lindex $docProject(extra) \
[lsearch -exact $docProject(name) $DocprojmodeVars(currentProject)]]
}
proc file::projectLicense {} {
global docProject DocprojmodeVars
set ret [lindex $docProject(license) \
[lsearch -exact $docProject(name) $DocprojmodeVars(currentProject)]]
if {$ret == ""} {
return "none"
} else {
return $ret
}
}
namespace eval functioncomments {}
##
# ----------------------------------------------------------------------
#
# "file::functionComment" --
#
# This procedure generates a nice little comment box like this one here.
#
# Results:
# Well it doesn't return anything, but it allows you to enter each item
# simply, moving from one to the next with Tab
#
# Side effects:
# Not much
#
# ----------------------------------------------------------------------
##
proc functioncomments::usual { {simple ""} {author 0} } {
global user
set fn [getSelect]
set fn [lindex $fn end]
beginningOfLine
set t "-------------------------------------------------------------------------\r"
append t "\r"
append t "\"$fn\" --\r"
append t "\r •description•\r"
if { $simple != "simple" } {
append t "\rResults:\r •results•\r\rSide effects:\r •side effects•\r"
}
if {$author} {
append t "\r--Version--Author------------------Changes-------------------------------"
append t "\r 1.0 $user(email) original\r"
}
append t "-------------------------------------------------------------------------"
set t [file::commentTextBlock $t]
elec::CenterInsertion $t
}
proc functioncomments::simple {} { return [functioncomments::usual simple 0]}
proc functioncomments::withAuthor {} { return [functioncomments::usual "" 1] }
proc file::commentTextBlock {text} {
set cc [commentCharacters "Paragraph"]
set c [lindex $cc 2]
regsub -all "\[\r\n\]" $text "\r${c}" text
return "[lindex $cc 0]\r[lindex $cc 2]${text}\r[lindex $cc 1]\r"
}
##
# -------------------------------------------------------------------------
#
# "file::functionCommentUpdate" --
#
# Handles updating of a version line like the one below
#
# --Version--Author------------------Changes-------------------------------
# 1.0 <darley@fas.harvard.edu> original
# 1.1 <darley@fas.harvard.edu> quickly updated with shift-F1
# -------------------------------------------------------------------------
##
proc functioncomments::update {} {
global user
set begin [lindex [commentCharacters Paragraph] 2]
goto [file::findLocally "${begin}--Version--Author"]
goto [nextLineStart [nextLineStart [getPos] ]]
goto [file::findLocally "${begin}-------"]
elec::Insertion "${begin} •Version• $user(email) •Changes•\r"
}
##
# -------------------------------------------------------------------------
#
# "file::findLocally" --
#
# Looks around for a particular sequence of characters (or a regexp) and
# returns the start of the closest fit, either fowards or backwards, or
# "" if no match was found.
# -------------------------------------------------------------------------
##
proc file::findLocally { chars {regexp 0} { pos "" } } {
if { $pos == "" } { set pos [getPos] }
set found1 [lindex [search -s -f 0 -n -r $regexp -- "$chars" $pos] 0]
set found2 [lindex [search -s -f 1 -n -r $regexp -- "$chars" $pos] 0]
if { $found1 != "" && $found2 != "" } {
if {[expr ([pos::math $pos + 0] - [pos::math $found1 + 0]) \
<= ([pos::math $found2 + 0] - [pos::math $pos + 0]) ]} {
return $found1
} else {
return $found2
}
}
# return whatever we can, possibly ""
if { $found1 != "" } {
return $found1
} else {
if { $found2 == "" } {
message "Couldn't find: $chars"
}
return $found2
}
}
##
# -------------------------------------------------------------------------
#
# "file::updateFileVersion" --
#
# Update the version number and information in the header block of a
# file. Copes with both my old and new formats.
#
# -------------------------------------------------------------------------
##
proc file::updateFileVersion {} {
global user
# in case the user wishes to return quickly
pushPosition
goto [minPos]
set begin [lindex [commentCharacters Paragraph] 2]
set pos [file::findLocally "_/_/_" 0]
if { $pos == "" || [pos::compare $pos > [pos::math [minPos] + 1000]]} {
set srch [quote::WhitespaceReg [quote::Regfind "${begin} " ]]
append srch {[0-9]+/[0-9]+/[0-9]+}
set pos [file::findLocally $srch 1]
if { $pos == "" } {
message "Couldn't find original version template."
set srch [quote::Regfind "${begin} "]
append srch "See header file for further information"
set pos [file::findLocally [quote::WhitespaceReg $srch]]
if { $pos != "" } {
set pos [nextLineStart $pos]
} else {
goto [minPos]
set pos [file::findLocally "${begin}\#\#\#"]
if { $pos == "" } { message "Couldn't find any header" ; return }
set pos [lindex [search -s -f 1 -n -- "${begin}\#\#\#" [nextLineStart $pos]] 0]
if { $pos == "" } { message "Couldn't find any header" ; return }
}
goto $pos
set t "${begin}\r"
append t "${begin} modified by rev reason\r"
append t "${begin} ---------- --- --- -----------\r"
append t "${begin} [file::paddedDate] $user(author_initials) 1.0 original\r"
insertText $t
select $pos [getPos]
return ""
} else {
# This is the normal case.
# Find the last version number
set p [minPos]
while {[pos::compare $p != $pos]} {
set pos $p
set p [file::findLocally $srch 1 [nextLineStart $p] ]
}
set pos [nextLineStart $pos]
}
} else {
# old style header
set pos [lineStart $pos]
replaceText $pos [nextLineStart $pos] ""
}
# Now pos is at the start of the line where we wish to insert
goto $pos
elec::Insertion "${begin} [file::paddedDate] $user(author_initials) •• ••\r"
message "Pop position to return to where you were."
return ""
}
proc file::paddedDate {{when ""}} {
if {$when == ""} { set when [now] }
return [string range "[lindex [mtime $when short] 0] " 0 9]
}
proc file::created {{convert 1}} {
if {[catch {getFileInfo [win::Current] info}]} {
if {$convert} {
return [mtime [now]]
} else {
return [now]
}
} else {
if {$convert} {
return [mtime $info(created)]
} else {
return $info(created)
}
}
}
##
# -------------------------------------------------------------------------
#
# "file::createHeader" --
#
# Insert a descriptive header into the current file. Needs to be
# tailored more to different modes, but isn't too bad right now.
#
# 'forcemode' will force the file into that mode via emacs-like mode
# entries on the top line of the file.
#
# 'parent' gives the name of a class from which the generated file
# descends (appropriate for C++, [incr Tcl] for example).
#
# -------------------------------------------------------------------------
##
proc file::createHeader { {template ""} {parent "" } } {
# Make sure the current project is compatible with this mode
file::coordinateProjectForMode
if {$parent == ""} {set parent "•parent•"}
if {$template == ""} { set template [list "" "" "Header" "\#" "" ""] }
# make the header
if {[lindex $template 1] != "Empty" } {
set t ""
set class [file::className]
if {$class == "Untitled"} {set class "•class name•"}
set file [win::CurrentTail]
set docHeadType [lindex $template 2]
if {$docHeadType != "None" } {
append t [file::topHeader]
if {$docHeadType != "Basic"} {
if {$docHeadType == "Source" || [file::isSource $file]} {
# it's a source file
append t " See header file for further information\r"
} elseif {$docHeadType == "Header" || $docHeadType == "*" && [file::isHeader $file]} {
global user
append t " Description: \r"
append t "\r"
append t " History\r"
append t "\r"
append t " modified by rev reason\r"
append t " ---------- --- --- -----------\r"
append t " [file::paddedDate [file::created 0]] $user(author_initials) 1.0 original\r"
} else {
# not header or source or basic... oh well!
}
}
append t "###################################################################"
set t [file::commentTextBlock $t]
global mode
global ${mode}::firstHeaderLine
if {[info exists ${mode}::firstHeaderLine]} {
regsub "\r" $t "[quote::Regsub [set ${mode}::firstHeaderLine]]\r" t
} else {
regsub "\r" $t "-*-${mode}-*-\r" t
}
}
set procName [lindex $template 3]
if {$procName != "\#" && [info commands $procName] == ""} {
global PREFS
if {[catch {uplevel \#0 source [list [file join $PREFS prefs.tcl]]}]} {
alertnote "An error occurred while loading \"prefs.tcl\""
global errorInfo
dumpTraces "prefs.tcl error" $errorInfo
error ""
}
}
if {[catch {append t [eval $procName [list $class] [list $parent] [lindex $template 5]]}]} {
alertnote "An error occurred while calling \"$procName\""
global errorInfo
dumpTraces "$procName error" $errorInfo
error ""
}
goto [minPos]
elec::Insertion $t
}
return ""
}
##
# -------------------------------------------------------------------------
#
# "file::createDocument" --
#
# Make a new document from a given template type.
#
# 'forcemode' will force the file into that mode via emacs-like mode
# entries on the top line of the file.
#
# -------------------------------------------------------------------------
##
proc file::createDocument { {winCreate ""} {forcemode "" } } {
# pick a template
# if [fileIsHeader $file]
global elec::DocTemplates mode DocprojmodeVars
# decide if its mode-specific or not
set f [lindex $winCreate 2]
if {$DocprojmodeVars(docTemplatesModeSpecific)} {
if {$forcemode != ""} {
set tlist [file::docTemplates $f $forcemode non]
} else {
set tlist [file::docTemplates $f $mode non]
}
} else {
set tlist [file::docTemplates $f "" non]
}
lappend tlist "<Create new document type>"
if {$non != ""} {
eval lappend tlist "----------------------------------------------------" [lsort $non]
}
set tchoice [listpick -p "Pick a document template to insert" -L "Default" $tlist]
if {$tchoice == "<Create new document type>"} {
set tchoice [file::newDocumentTemplate 1]
}
if {$tchoice == "----------------------------------------------------"} { error "" }
set tinfo [file::docTemplateInfo $tchoice]
set subTypes [lindex $tinfo 5]
if {$subTypes != ""} {
# replace the list of options with just the one selected
set tinfo [lreplace $tinfo 5 5 [listpick -p "Pick a document subtype of $tchoice" $subTypes]]
}
if {$forcemode == "" && [lindex $tinfo 0] != "*"} {
set forcemode [lindex $tinfo 0]
}
if {$winCreate != ""} {
eval $winCreate
}
if { $forcemode != "" && $mode != $forcemode} {
changeMode $forcemode
}
# we need to do this to stop modes switching later if this file isn't
# obviously a '$mode' file.
global win::Modes
set win::Modes($f) $mode
# set the project
Docproj::changeProject [lindex $tinfo 4]
# if the current project doesn't like this mode, then switch
file::coordinateProjectForMode
return $tinfo
}
proc file::docTemplates { {f ""} {modeSpecific ""} {other ""}} {
global elec::DocTemplates
if {$other != ""} { upvar $other noList }
set tlist ""
set noList ""
if {$f != "" && $f != "Untitled"} {
set m [file::whichModeForWin $f]
foreach t ${elec::DocTemplates} {
if {[file::docTemplateMatchExt $t $f $m]} {
lappend tlist [lindex $t 1]
} else {
lappend noList [lindex $t 1]
}
}
} else {
foreach t ${elec::DocTemplates} {
if {$modeSpecific == "" || [string match [lindex $t 0] $modeSpecific]} {
lappend tlist [lindex $t 1]
} else {
lappend noList [lindex $t 1]
}
}
}
return [lsort $tlist]
}
proc file::docTemplateMatchExt {t f {m ""}} {
if {$m == ""} {set m [file::whichModeForWin $f]}
# match everything to a file with no particular extension
if {$m == "Text"} { return 1 }
set l [lindex $t 0]
set mMatch [expr [lsearch -exact $l $m] != -1]
switch -- [lindex $t 2] {
"None" -
"Basic" -
"*" {
if {$l == "*"} {
return 1
} else {
return $mMatch
}
}
"Header" {
if {$mMatch} {
return [file::isHeader $f $m]
}
}
"Source" {
if {$mMatch} {
return [file::isSource $f $m]
}
}
}
return 0
}
proc file::docTemplateInfo {name} {
global elec::DocTemplates
foreach t ${elec::DocTemplates} {
if {$name == [lindex $t 1]} {
return $t
}
}
}
proc file::docTemplateIndex {name} {
set i 0
global elec::DocTemplates
foreach t ${elec::DocTemplates} {
if {$name == [lindex $t 1]} {
return $i
}
incr i
}
}
proc file::notTextMode {} {
global mode mode::features
if { $mode == "Text" } {
# we probably don't want Text mode
set m [listpick -p "Pick a mode:" -L "Text" [array names mode::features]]
if { $m == "" } {set m "Text"}
changeMode $m
}
}
##
# -------------------------------------------------------------------------
#
# "file::topHeader" --
#
# Inserts the top part of a descriptive header into the current file
# -------------------------------------------------------------------------
##
proc file::topHeader { } {
global user
set file [win::CurrentTail]
if {[catch {getFileInfo [win::Current] info}]} {
set created [mtime [now]]
set last_update $created
} else {
set created [mtime $info(created)]
set last_update [mtime $info(modified)]
}
append t "###################################################################\r"
if {[file::projectName] != "*"} {
append t " [file::projectName] - [file::projectAddendum]\r"
}
append t "\r"
append t " FILE: \"" $file "\"\r"
append t " created: $created \r"
append t " last update: $last_update \r"
append t " Author: $user(author)\r"
append t " E-mail: $user(email)\r"
if {$user(organisation) != ""} {
append t " mail: $user(organisation)\r"
}
if {$user(address) != ""} {
append t " $user(address)\r"
}
if {$user(www) != ""} {
append t " www: $user(www)\r"
}
append t " \r"
append t [file::[file::projectLicense]]
if {[set e [file::projectExtra]] != ""} {
append t "[breakIntoLines $e]\r \r"
}
return $t
}
##
# -------------------------------------------------------------------------
#
# "file::className" --
#
# Extract root of file name as a class name for the file (obviously most
# relevant to C++)
# -------------------------------------------------------------------------
##
proc file::className {} { return [file::baseName [win::CurrentTail]] }
##
# -------------------------------------------------------------------------
#
# "file::coordinateProjectForMode" --
#
# When we create a new file or header automatically, it contains
# information about our current project (as defined in docProject(...)).
# Unfortunately we often forget to select the correct project first.
# This procedure makes sure that your project is compatible with the
# current mode, given the information in the 'docProject' array. If it isn't
# then the current project is changed if a better match can be found.
#
# Results:
# None
#
# Side effects:
# The current project may be changed
# -------------------------------------------------------------------------
##
proc file::coordinateProjectForMode {} {
global mode docProject
set currProj [file::projectName]
set projModes [lindex $docProject(default_modes) \
[lsearch -exact $docProject(name) [file::projectName]]]
if { $projModes != "" && [lsearch -exact $projModes $mode] == -1 } {
# this project doesn't like this mode.
# see if there's a better one
foreach modeLists $docProject(default_modes) {
if { [lsearch -exact $modeLists $mode] != -1 } {
# found a fit
set index [lsearch -exact $docProject(default_modes) $modeLists]
set proj [lindex $docProject(name) $index]
Docproj::changeProject "$proj"
return
}
}
}
}
proc file::createNewClass {} {
global mode
# if the current project doesn't like this mode, then switch
file::coordinateProjectForMode
beep
set class [statusPrompt "A name for the new class:"]
set parent [statusPrompt "Descended from:" ]
switch -- $mode {
"C" -
"C++" {
file::createHeader [file::createDocument "new -n ${class}.cc" C++] $parent
file::createHeader [file::createDocument "new -n ${class}.h" C++] $parent
}
"Tcl" {
file::createHeader [file::createDocument "new -n ${class}.tcl" Tcl] $parent
}
default {
message "No class procedure defined for your mode. Why not write one yourself?"
}
}
}
##
# -------------------------------------------------------------------------
#
# "file::updateGeneralDate" --
#
# Updates the date in the header of a file. Normally this is the
# 'last update' date, but we can override that if desired.
# -------------------------------------------------------------------------
##
proc file::updateGeneralDate { name {patt ""} {time ""}} {
if {$patt == ""} {set patt {last update: }}
regsub -all { } $patt "\[ \t\]" spatt
set pos [getPos]
set end [selEnd]
set hour {[0-9][0-9]?(:|\.)[0-9][0-9]((:|\.)[0-9][0-9])?([ \t][APap][Mm])?}
set date {[0-9][0-9]?(/|\.|\-)[0-9][0-9]?(/|\.|\-)[0-9][0-9]([0-9][0-9])?}
append spatt "\[ \t\]*" $date "(\[ \t]\{?" $hour {\}?)?}
set datePos [search -s -n -f 1 -r 1 -m 0 -l [pos::math [minPos] + 1000] $spatt [minPos]]
if {![llength $datePos]} {return}
if {$time == ""} {set time [mtime [now] short]}
if {[eval getText $datePos] == $time} {return}
eval replaceText $datePos [list $patt $time]
select $pos $end
}
proc file::updateDate { {name ""} } {
set fr [win::Current]
if { $name == "" } {
set name $fr
}
if { $name != $fr } {
bringToFront $name
file::updateGeneralDate $name
bringToFront $fr
} else {
file::updateGeneralDate $name
}
}
proc file::updateCreationDate { name } {
if {[catch {getFileInfo [stripNameCount [win::Current]] info}]} {
set created [mtime [now]]
} else {
set created [mtime $info(created)]
}
file::updateGeneralDate $name "created" $created
}
proc file::newFunction {} {
elec::Insertion "[file::className]::•name•(•args•){\r\t•body•\r}\r"
}
proc global::newDocumentTemplate { {subCall 0} } {
if {[catch {set newT [global::_editDocumentTemplate]}]} {return}
global elec::DocTemplates
lappend elec::DocTemplates $newT
# save it permanently
global modifiedVars
lappend modifiedVars elec::DocTemplates
# add template to "prefs.tcl"
set procedure [lindex $newT 3]
set subproj [lindex $newT 5]
if {$procedure != "\#"} {
set def [file::_getDefault "Do you want to use this as the template?" t]
set t "\r"
append t "proc $procedure \{docname parentdoc"
if {$subproj != ""} { append t " subtype " }
append t "\} \{\r"
append t "\t# You must fill this in\r"
if {$subproj != ""} { append t "\t# Possible 'subtypes' are: $subproj\r" }
append t $def
append t "\r\treturn \$t\r\}\r"
addUserLine $t
if {[askyesno "I've added a template for the procedure to your 'prefs.tcl'. Do you want to edit it now?"] == "yes"} {
global::editPrefsFile
goto [maxPos]
if {$subCall} {
alertnote "Once you've finished editing, hit cmd-N to go back and create a new document."
# so our calling proc stops
error "Editing"
}
}
}
return [lindex $newT 1]
}
proc file::_varValue {var} {
upvar $var a
if {[info exists a]} {
return $a
} else {
return ""
}
}
proc file::_getDefault { text {default ""} {var ""}} {
if {[isSelection]} {
if {[askyesno "I notice you've selected some text. $text"] == "yes"} {
set default [getSelect]
}
}
if {$default == ""} {
set default [getline "Enter template text (you can edit it later)" $default]
}
if {$var != ""} {
return [elec::_MakeIntoInsertion $default $var]
} else {
return $default
}
}
proc global::_editDocumentTemplate {{def ""}} {
global DocprojmodeVars
if {$def == ""} {
set title "Create a new document template"
set def {"" "" "By File Extension" "t_XXX" $DocprojmodeVars(currentProject) ""}
set new 1
} else {
set title "Edit document template"
set new 0
}
global docProject
set name ""
while { $name == ""} {
set y 40
set yb 220
set res [eval dialog -w 380 -h 340 \
[dialog::title $title 380] \
[dialog::button "OK" 290 yb] \
[dialog::button "Cancel" 290 yb] \
[dialog::textedit "Descriptive Name" [lindex $def 1] 10 y 15] \
[dialog::textedit "Modes (blank = all)" [lindex $def 0] 10 y 15] \
[dialog::textedit "Procedure name" [lindex $def 3] 10 y 15] \
[dialog::text "Descriptive header for this document template" 10 y] \
[dialog::text "(if 'Source', or 'Header', the mode must define" 10 y] \
[dialog::text "headerSuffices and sourceSuffices vars)" 10 y] \
[dialog::menu 10 y [list "None" "-" "Basic" "Source" "Header" "Either"] [lindex $def 2]] \
[dialog::text "Project name" 10 y] \
[dialog::menu 10 y $docProject(name) [lindex $def 4]] \
[dialog::textedit "List of sub-types" [lindex $def 5] 10 y 30] \
]
if {[lindex $res 1]} { error "Cancel" }
set i 1
foreach var {name modes procedure filetype proj subproj} {
set $var [lindex $res [incr i]]
}
if {$name == ""} { beep ; message "You must enter a name." }
}
if {$modes == ""} {set modes "*"}
if {$filetype == "Either"} {set filetype "*"}
if {$proj == "None"} {set proj "*"}
if {$procedure == ""} {set procedure "\#"}
return [list $modes $name $filetype $procedure $proj $subproj]
}
proc global::editDocumentTemplate {} {
global modifiedVars elec::DocTemplates
set tlist [file::docTemplates]
if {[catch {set l [listpick -p "Which document template do you want to edit?" $tlist]}]} {
return
}
set lind [file::docTemplateIndex $l]
if {[catch {set l [global::_editDocumentTemplate [file::docTemplateInfo $l]]}]} {
return
}
set elec::DocTemplates [lreplace ${elec::DocTemplates} $lind $lind $l]
lappend modifiedVars elec::DocTemplates
}
proc global::removeDocumentTemplate {} {
global modifiedVars elec::DocTemplates
set tlist [file::docTemplates]
if {[catch {set l [listpick -p "Which document template shall I permanently remove?" $tlist]}]} {
return
}
set l [file::docTemplateIndex $l]
set elec::DocTemplates [lreplace ${elec::DocTemplates} $l $l]
lappend modifiedVars elec::DocTemplates
}
## Create this sort of stuff.
# set docProject(name) [list "None" "EvoX" "Vince's Additions" "Cpptcl"]
# set docProject(addendum) { {none} {evolution in complex systems} \
# {an extension package for Alpha} {connecting C++ with Tcl} }
# set docProject(default_modes) { {} {C C++} {Tcl} {C C++ Tcl}}
##
proc global::newProject {} {
global docProject
if {[catch {global::_editProject} res]} {return}
set i -1
foreach var {name addendum license extra default_modes} {
lappend docProject($var) [lindex $res [incr i]]
}
global modifiedArrVars
lappend modifiedArrVars docProject
addMenuItem -m {Current Project} [lindex $res 0]
Docproj::changeProject [lindex $res 0]
}
proc global::_editProject {{def ""}} {
if {$def == ""} {
set title "Create a new project"
set def [list "Vince's Additions" \
"an extension package for Alpha" "seeFileLicenseTerms" \
"See the file \"license.terms\" for information on usage and redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES." ""]
} else {
set title "Edit a project"
}
set y 40
set yb 270
global elec::LicenseTemplates
set res [eval dialog -w 380 -h 325 \
[dialog::title $title 360] \
[dialog::button "OK" 290 yb] \
[dialog::button "Cancel" 290 yb] \
[dialog::textedit "Short Descriptive Name" [lindex $def 0] 10 y 15] \
[dialog::textedit "Longer Description to append to the above" [lindex $def 1] 10 y 25] \
[dialog::text "License type for header comments" 10 y] \
[dialog::menu 10 y ${elec::LicenseTemplates} [lindex $def 2]] \
[dialog::textedit "Additional text for end of header comments" [lindex $def 3] 10 y 35 5] \
[dialog::textedit "Modes (blank = all)" [lindex $def 4] 10 y 15] \
]
if {[lindex $res 1]} { error "Cancel" }
return [lrange $res 2 6]
}
proc global::editProject {} {
global docProject modifiedArrVars
if {[catch {set l [listpick -p "Which project do you wish to edit?" \
-L [file::projectName] $docProject(name)]}]} {
return
}
set item [lsearch -exact $docProject(name) $l]
foreach uvar {name addendum license extra default_modes} {
lappend def [lindex $docProject($uvar) $item]
}
if {[catch {global::_editProject $def} def]} {return}
set i -1
foreach uvar {name addendum license extra default_modes} {
set docProject($uvar) [lreplace $docProject($uvar) $item $item [lindex $def [incr i]]]
}
lappend modifiedArrVars docProject
}
proc global::removeProject {} {
global docProject modifiedArrVars
if {[catch {set l [listpick -p "Which project shall I permanently remove?" $docProject(name)]}]} {
return
}
set item [lsearch -exact $docProject(name) $l]
foreach uvar {name addendum license extra default_modes} {
set docProject($uvar) [lreplace $docProject($uvar) $item $item]
}
lappend modifiedArrVars docProject
if {[file::projectName] == $l} {
Docproj::changeProject "None"
}
deleteMenuItem -m {Current Project} $l
}